package net.keebook.webapp.dao;

import java.util.List;

import javax.ejb.Stateless;
import javax.inject.Inject;
import javax.persistence.Query;

import net.keebook.webapp.entity.GeneratorPreferences;
import net.keebook.webapp.entity.KeeBookAccess;
import net.keebook.webapp.entity.User;


@Stateless
public class UserDao extends Dao<User> {
	@Inject
	private KeeBookDao keeBookDao;
	
	@Override
	public void store(User item) {
		super.store(item);
	}
	
	@Override
	public void update(User item) {
		super.update(item);
	}
	
	@Override
	public User get(Long id) {
		return super.get(id);
	}
	
	@Override
	public User get(String id) {
		return super.get(id);
	}
	
	@Override
	public void delete(User item) {
		getEntityManager().createQuery("DELETE FROM AccountConfirmation a WHERE a.user.id = :userId").setParameter("userId", item.getId()).executeUpdate();
		getEntityManager().createQuery("DELETE FROM LoginMemory a WHERE a.user.id = :userId").setParameter("userId", item.getId()).executeUpdate();
		getEntityManager().createQuery("DELETE FROM ShareRequest a WHERE a.invitingUser.id = :userId").setParameter("userId", item.getId()).executeUpdate();
		
		// Delete user from access lists
		List<KeeBookAccess> accessList = getKeeBookDao().getAccessListForUser(item.getId());
		for (KeeBookAccess kba : accessList) {
			getEntityManager().createQuery("DELETE FROM KeeBookAccess a WHERE a.pk.user.id = :userId").setParameter("userId", item.getId()).executeUpdate();
			// Delete entire kee book if user was the only one who could access it
			// TODO What if users remain, but these are not on the OWNER ACL
			if (getKeeBookDao().getAccessListForKeeBook(kba.getKeeBook().getId()).isEmpty()) {
				getKeeBookDao().delete(kba.getKeeBook());
			}
		}
		
		GeneratorPreferences generatorPreferences = item.getGeneratorPreferences();
		if (generatorPreferences != null) {
			generatorPreferences = getEntityManager().merge(generatorPreferences);
			getEntityManager().remove(generatorPreferences);
		}
		
		super.delete(item);
	}
	
	public void store(GeneratorPreferences generatorPreferences) {
		getEntityManager().persist(generatorPreferences);
	}
	
	public void update(GeneratorPreferences generatorPreferences) {
		getEntityManager().merge(generatorPreferences);
	}
	
	public User getPasswordUserByUsername(String username) {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.username = :username AND u.loginMethod = 'PASSWORD'");
		query.setParameter("username", username);
		@SuppressWarnings("unchecked")
		List<User> list = query.getResultList();
		if (list.isEmpty()) {
			return null;
		}
		getEntityManager().detach(list.get(0));
		return list.get(0);
	}
	
	public User getUserByUsername(String username) {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.username = :username");
		query.setParameter("username", username);
		@SuppressWarnings("unchecked")
		List<User> list = query.getResultList();
		if (list.isEmpty()) {
			return null;
		}
		getEntityManager().detach(list.get(0));
		return list.get(0);
	}
	
	public User getUserByOauthId(String oauthId) {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.oauthId = :oauthId");
		query.setParameter("oauthId", oauthId);
		@SuppressWarnings("unchecked")
		List<User> list = query.getResultList();
		if (list.isEmpty()) {
			return null;
		}
		getEntityManager().detach(list.get(0));
		return list.get(0);
	}
	
	public User getPasswordUserByEmail(String email) {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.email = :email AND u.loginMethod = 'PASSWORD'");
		query.setParameter("email", email);
		@SuppressWarnings("unchecked")
		List<User> list = query.getResultList();
		if (list.isEmpty()) {
			return null;
		}
		getEntityManager().detach(list.get(0));
		return list.get(0);
	}
	
	public User getUserByEmail(String email) {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.email = :email");
		query.setParameter("email", email);
		@SuppressWarnings("unchecked")
		List<User> list = query.getResultList();
		if (list.isEmpty()) {
			return null;
		}
		getEntityManager().detach(list.get(0));
		return list.get(0);
	}
	
	@SuppressWarnings("unchecked")
	public List<User> getList() {
		Query query = getEntityManager().createQuery("FROM User u ORDER BY u.username");
		return detachAll(query.getResultList());
	}
	
	@SuppressWarnings("unchecked")
	public List<User> getListOfPasswordUsers() {
		Query query = getEntityManager().createQuery("FROM User u WHERE u.loginMethod = 'PASSWORD' ORDER BY u.username");
		return detachAll(query.getResultList());
	}

	public KeeBookDao getKeeBookDao() {
		return keeBookDao;
	}

	public void setKeeBookDao(KeeBookDao keeBookDao) {
		this.keeBookDao = keeBookDao;
	}
}
